<?php
if(!defined('BASEPATH')) exit('No direct script access allowed');
/* 
	短信类
*/
require_once(APPCOMMON.'libraries/Http.php');

class Smslib extends Http{
	
	protected $url_send = 'https://dysmsapi.aliyuncs.com/';
	
	protected $_config;
	
	public function __construct($option = array(), $confname = 'aliyunsms'){
		$CI = &get_instance();
		$CI->load->config($confname, true);
		$config = $CI->config->item($confname);
		if($option){
			foreach($option as $key => $value){
				$config[$key] = $value;
			}
		}
		if(!$config['accessKeyId'] || !$config['accessKeySecret']){
			exit('smslib config error');
		}
		$this->_config = $config;
	}
	
	// 一次请求中向多个不同的手机号码发送
	// 同样内容的短信
	public function send($phone, $options){
		if(!$phone){
			return false;
		}
		if(!is_array($phone)){
			$phone = array($phone);
		}
		$options['action'] = 'SendSms';
		$data = array_merge([
			'PhoneNumbers' => implode(',', $phone),
			'SignName' => $options['signName'] ? $options['signName'] : $this->_config['signName'],
			'TemplateCode' => $options['tplCode'],
			'TemplateParam' => json_encode($options['tplParam']),
		], $this->pulic_params($options));
		$accessSecret = $options['accessKeySecret'] ? $options['accessKeySecret'] : $this->_config['accessKeySecret'];
		$data['Signature'] = $this->make_sign($data, $accessSecret);
		$req = $this->request($this->url_send, $data);
		if($req){
			$res = json_decode($req, true);
			if('OK' === $res['Code']){
				return true;
			}
		}
		return $req;
	}
	
	public function send_code($phone, $code, $type = 'reg'){
		$tplCode = $this->get_tplcode($type);
		if(!$tplCode){
			return false;
		}
		return $this->send($phone, [
			'tplCode' => $tplCode,
			'tplParam' => [
				'code' => $code
			]
		]);
	}
	
	public function send_notice($phone, $param, $type = 'signup_success'){
		$tplCode = $this->get_tplcode($type);
		if(!$tplCode){
			return false;
		}
		return $this->send($phone, [
			'tplCode' => $tplCode,
			'tplParam' => $param
		]);
	}
	
	// 一次请求中分别向多个不同的手机号码发送
	// 不同签名的短信
	public function batch_send($phones, $options){
		if(!$phones){
			return false;
		}
		if(!is_array($phones)){
			$phones = array($phones);
		}
		$signName = $options['signName'];
		if(!$signName || !is_array($signName)){
			$_sign = $options['signName'] ? $options['signName'] : $this->_config['signName'];
			$signName = [];
			for($i = 0; $i < count($phones); $i++){
				$signName[] = $_sign;
			}
		}
		$options['action'] = 'SendBatchSms';
		$data = array_merge([
			'PhoneNumberJson' => json_encode($phones),
			'SignNameJson' => json_encode($signName),
			'TemplateCode' => $options['tplCode'],
			'TemplateParamJson' => json_encode($options['tplParam']),
		], $this->pulic_params($options));
		$accessSecret = $options['accessKeySecret'] ? $options['accessKeySecret'] : $this->_config['accessKeySecret'];
		$data['Signature'] = $this->make_sign($data, $accessSecret);
		$req = $this->request($this->url_send, $data);
		if($req){
			$res = json_decode($req, true);
			if('OK' === $res['Code']){
				return true;
			}
		}
		return $req;
	}
	
	public function batch_send_notice($phones, $params, $type){
		$tplCode = $this->get_tplcode($type);
		if(!$tplCode){
			return false;
		}
		if(isset($params['signName'])){
			$signName = $params['signName'];
			unset($params['signName']);
		}
		if(isset($params['data'])){
			$params = $params['data'];
		}
		return $this->batch_send($phones, [
			'tplCode' => $tplCode,
			'tplParam' => $params,
			'signName' => $signName
		]);
	}
	
	// 公共请求参数
	private function pulic_params($options){
		return [
			'Format' => 'json',
			'AccessKeyId' => $options['accessKeyId'] ? $options['accessKeyId'] : $this->_config['accessKeyId'],
			'Action' => $options['action'] ? $options['action'] : 'SendSms',
			'SignatureMethod' => 'HMAC-SHA1',
			'SignatureNonce' => $this->rand_str(),
			'SignatureVersion' => '1.0',
			'Timestamp' => gmdate ( 'Y-m-d\TH:i:s\Z' ),
			'Version' => '2017-05-25'
		];
	}
	
	// 获取短信模板id
	private function get_tplcode($type){
		switch($type){
			case 'reg': // 注册
				$return = 'SMS_187241239';
				break;
			case 'signup_success': // 报名提交成功
				$return = 'SMS_187271375';
				break;
			case 'signup_passed': // 报名审核通过
				$return = 'SMS_189836341';
				break;
			default:
				return false;
		}
		return $return;
	}
	
	private function rand_str($length = 16){
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
		$str = '';
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}
	
	private function special_encode($str) {
        $str = urlencode($str);
        $str = preg_replace('/\+/', '%20', $str);
        $str = preg_replace('/\*/', '%2A', $str);
        $str = preg_replace('/%7E/', '~', $str);
        return $str;
    }
	
	private function make_sign($data, $accessSecret){
		ksort($data);
		$str = '';
		foreach($data as $k => $v){
			$str .= ($str ? '&' : ''). $this->special_encode($k) . '=' . $this->special_encode($v);
		}
		$str_sign = 'GET&%2F&'. $this->special_encode($str);
		$signature = base64_encode(hash_hmac('sha1', $str_sign, $accessSecret . '&', true));
		return $signature;
    }
	
}